import 'package:dio/dio.dart';
import 'package:injectable/injectable.dart';

@singleton
class DioClient {
  late final Dio _dio;
  final Map<String, Response> _cache = {};
  final Map<String, CancelToken> _requestTokens = {};

  DioClient() {
    _dio = Dio(
      BaseOptions(
        baseUrl: 'https://api.example.com',
        connectTimeout: const Duration(seconds: 5),
        receiveTimeout: const Duration(seconds: 3),
      ),
    )..interceptors.addAll([
        LogInterceptor(responseBody: true),
        InterceptorsWrapper(
          onRequest: (options, handler) {
            final requestKey = options.uri.toString();
            if (_requestTokens.containsKey(requestKey)) {
              // 如果请求已经存在，取消当前请求
              _requestTokens[requestKey]?.cancel('Cancelled duplicate request');
            }
            // 为新请求创建一个取消令牌
            final cancelToken = CancelToken();
            _requestTokens[requestKey] = cancelToken;
            options.cancelToken = cancelToken;
            return handler.next(options);
          },
          onResponse: (response, handler) {
            final requestKey = response.requestOptions.uri.toString();
            _cache[requestKey] = response;
            _requestTokens.remove(requestKey);
            return handler.next(response);
          },
          onError: (DioError e, handler) {
            final requestKey = e.requestOptions.uri.toString();
            _requestTokens.remove(requestKey);
            return handler.next(e);
          },
        ),
      ]);
  }

  Future<Response> get(String path, {Map<String, dynamic>? queryParameters}) async {
    try {
      final response = await _dio.get(path, queryParameters: queryParameters);
      return response;
    } catch (e) {
      rethrow;
    }
  }

  Future<Response> post(String path, {Map<String, dynamic>? data}) async {
    try {
      final response = await _dio.post(path, data: data);
      return response;
    } catch (e) {
      rethrow;
    }
  }

  Dio get dio => _dio;
} 